package com.sensoro.beacon.kit;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;

import java.util.ArrayList;

/**
 * Created by Sensoro on 14-8-22.
 */
abstract class SensoroBeaconService extends Service {
	private static final String SBK_PREF = "A";
	private static final String PREF_APP_SERVICE_CLASS_NAME = "B";
	private static final String PREF_APP_SERVICE_PACKAGE_NAME = "C";

	// 服务重启时间
	private static final int RESTART_ALARM_INTERVAL = 20 * 1000;
	private static final int RESTART_ALARM_TIME = 10 * 1000;

    private Context context;
    private BeaconProcessService beaconProcessService;
    private BeaconManagerListener beaconManagerListener;

	private SharedPreferences sharedPreferences;
	// service是否运行标志。系统没有置false，默认为如果被系统kill，则自动置为false。
	private boolean serviceIsRunning = false;

	@Override
	public void onCreate() {
		Log.v("Sensoro", "onCreate SensoroBeaconService");
		super.onCreate();
	}

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
		Log.v("Sensoro", "onStartCommand SensoroBeaconService");
        context = this;
		
		serviceIsRunning = true;
		if (intent != null) {
			// 保存app启动的service名称和包名
			saveAppIntent(intent);
		}
		// 定时重启service
//		timerRestartService();
		
        beaconManagerListener = new BeaconManagerListener() {
            @Override
            public void onNewBeacon(Beacon beacon) {
				SensoroBeaconService.this.onNewBeacon(beacon);
            }

            @Override
            public void onGoneBeacon(Beacon beacon) {
				SensoroBeaconService.this.onGoneBeacon(beacon);
            }

            @Override
            public void onUpdateBeacon(ArrayList<Beacon> beacons) {
				SensoroBeaconService.this.onUpdateBeacon(beacons);
            }
        };

        // bind BeaconProcessService
        bindBeaconProcessService();

        // 返回 START_STICKY，允许服务自动重启
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    // 绑定 BeaconProcessService
    private void bindBeaconProcessService() {
        Intent serviceIntent = new Intent();
        serviceIntent.setClass(context, BeaconProcessService.class);
        bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            BeaconProcessService.BeaconProcessServiceBinder beaconProcessServiceBinder = (BeaconProcessService.BeaconProcessServiceBinder) iBinder;
            beaconProcessService = beaconProcessServiceBinder.getService();
            beaconProcessService.registerListener(beaconManagerListener);
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            if (beaconProcessService != null) {
                beaconProcessService.unregisterListener(beaconManagerListener);
            }
        }
    };

    /**
	 * 发现一个beacon回调 <br/>
     * callback when an beacon appear
     *
	 * @param beacon
	 *            被发现的beacon <br/>
	 *            appeared beacon
     */
    abstract public void onNewBeacon(Beacon beacon);

    /**
	 * 消失一个beacon回调 <br/>
     * callback when an beacon disappear
     *
	 * @param beacon
	 *            消失的beacon <br/>
	 *            disappeared beacon
     */
    abstract public void onGoneBeacon(Beacon beacon);

    /**
     * 定时更新当前所在beacon列表
     * <p/>
     * <br/>
     * regularly update the current beacon list
     *
	 * @param beacons
	 *            当前所在的beacon <br/>
	 *            current beacon list
     */
    abstract public void onUpdateBeacon(ArrayList<Beacon> beacons);

	/**
	 * 保存app启动的service名称和包名
	 * 
	 * @author VegeChou
	 */
	private void saveAppIntent(Intent intent) {
		String className = intent.getComponent().getClassName();
		String pkgName = intent.getComponent().getPackageName();
		if (sharedPreferences == null) {
			initSharedPreferences();
		}
		Editor editor = sharedPreferences.edit();
		editor.putString(PREF_APP_SERVICE_CLASS_NAME, className);
		editor.putString(PREF_APP_SERVICE_PACKAGE_NAME, pkgName);
		editor.commit();
	}

	private void initSharedPreferences() {
		sharedPreferences = getSharedPreferences(SBK_PREF, Context.MODE_PRIVATE);
	}

	/**
	 * service被移除时，10秒钟之后重启该service
	 * 
	 * @author VegeChou
	 */
	@Override
	public void onTaskRemoved(Intent rootIntent) {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
			Intent restartIntent = new Intent();
			ComponentName component = getUserComponentName();
			restartIntent.setComponent(component);

			PendingIntent restartServicePI = PendingIntent.getService(getApplicationContext(), 1, restartIntent, PendingIntent.FLAG_ONE_SHOT);
			AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
			alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + RESTART_ALARM_TIME, restartServicePI);
			// 进入后台模式
			if (beaconProcessService!= null) {
				beaconProcessService.setBackgroundMode(true);
			}
		}
	}

	/**
	 * 获取app启动service名称和包名
	 * 
	 * @return
	 * @author VegeChou
	 */
	private ComponentName getUserComponentName() {
		ComponentName componentName = null;
		String className = sharedPreferences.getString(PREF_APP_SERVICE_CLASS_NAME, null);
		String pkgName = sharedPreferences.getString(PREF_APP_SERVICE_PACKAGE_NAME, null);
		if (className != null && pkgName != null) {
			componentName = new ComponentName(pkgName, className);
		}
		return componentName;
	}

	/**
	 * 定时重启service函数。每20秒重启一次服务。该方法是为了解决4.4.2版本系统的bug(
	 * onStartCommond返回START_STICKY,service被杀死不能重启)
	 * 
	 * @author VegeChou
	 */
	private void timerRestartService() {
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
			final Intent restartIntent = new Intent();
			ComponentName component = getUserComponentName();
			restartIntent.setComponent(component);
			final AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
			Handler restartServiceHandler = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					// Create a pending intent
					if (serviceIsRunning) {
						return;
					}
					PendingIntent pintent = PendingIntent.getService(getApplicationContext(), 0, restartIntent, 0);
					alarmMgr.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + RESTART_ALARM_TIME, pintent);
					sendEmptyMessageDelayed(0, RESTART_ALARM_INTERVAL);
				}
			};
			restartServiceHandler.sendEmptyMessageDelayed(0, 0);
		}
	}
}
